//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------


#include <stdio.h>
#include <string.h>
#include "Gun.h"


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// shot manager class
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------------
CShotManager::CShotManager() {

  m_vstShot.clear();
}


//-----------------------------------------------------------------------------
// destructor
//-----------------------------------------------------------------------------
CShotManager::~CShotManager() {

  m_vstShot.clear();
}


//-----------------------------------------------------------------------------
// add a shot to the manager
//-----------------------------------------------------------------------------
void CShotManager::AddShot(SShot stShot) {

  m_vstShot.push_back(stShot);
}


void CShotManager::AddHit() {
    hits += 1;
}

//-----------------------------------------------------------------------------
// update
//-----------------------------------------------------------------------------
void CShotManager::Update(float fDeltaTimeSeconds) {

  //aux vars
  vector<SShot>::iterator itstShot;
  int nCount;

  for (nCount = 0; nCount < (int)m_vstShot.size(); nCount++) {

    itstShot = m_vstShot.begin() + nCount;

    if (itstShot->fLife > 0.0f) {

      itstShot->afPos[0] += itstShot->afDir[0] * fDeltaTimeSeconds * itstShot->fSpeed;
      itstShot->afPos[1] += itstShot->afDir[1] * fDeltaTimeSeconds * itstShot->fSpeed;
      itstShot->afPos[2] += itstShot->afDir[2] * fDeltaTimeSeconds * itstShot->fSpeed;

      itstShot->fLife -= (itstShot->fSpeed * fDeltaTimeSeconds);

      if (itstShot->fLife < 0.0f) {

        m_vstShot.erase(itstShot);
        nCount--;
      }
    }
  }
}


//-----------------------------------------------------------------------------
// draw shots
//-----------------------------------------------------------------------------
void CShotManager::Draw() {

  //aux vars
  vector<SShot>::iterator itstShot;

  for (itstShot = m_vstShot.begin(); itstShot != m_vstShot.end(); itstShot++) {

    glPushMatrix();

    glTranslatef(itstShot->afPos[0], itstShot->afPos[1], itstShot->afPos[2]);
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    itstShot->poParticle->Draw();

    glPopMatrix();
  }
}


//-----------------------------------------------------------------------------
// enable light for shots
//-----------------------------------------------------------------------------
void CShotManager::SetLights() {

  //aux vars
  vector<SShot>::reverse_iterator itstShot;
  int nCount = 0;

  for (nCount = 0, itstShot = m_vstShot.rbegin(); itstShot != m_vstShot.rend(); itstShot++, nCount++) {

    if (nCount >= 7)
      break;

    if (itstShot->fLife > 0.0f) {

      float afPosition[] = {itstShot->afPos[0], itstShot->afPos[1], itstShot->afPos[2], 1.0f};
      float afAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f};
      float afDiffuse[] = {0.8f, 0.8f, 0.1f, 1.0f};
      float afSpecular[] = {0.8f, 0.8f, 0.1f, 1.0f};
      float afLightDirection[] = {0.0f, -1.0f, 0.0f, 1.0f};

      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT1 + nCount);

      glLightf(GL_LIGHT1 + nCount, GL_CONSTANT_ATTENUATION,  0.000f);
      glLightf(GL_LIGHT1 + nCount, GL_LINEAR_ATTENUATION,    0.000f);
      glLightf(GL_LIGHT1 + nCount, GL_QUADRATIC_ATTENUATION, 0.100f);
      glLightfv(GL_LIGHT1 + nCount, GL_POSITION, afPosition);
      glLightfv(GL_LIGHT1 + nCount, GL_AMBIENT,  afAmbient);
      glLightfv(GL_LIGHT1 + nCount, GL_DIFFUSE,  afDiffuse);
      glLightfv(GL_LIGHT1 + nCount, GL_SPECULAR, afSpecular);
    }
    else {

      glDisable(GL_LIGHT1 + nCount);
    }
  }
  for (nCount; nCount < 7; nCount++) {

    glDisable(GL_LIGHT1 + nCount);
  }
}


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Gun Class
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------------
CGun::CGun() {

  m_poParticle = NULL;

  m_fSpeed    = 0.0f;
  m_fDamage   = 0.0f;
  m_fFireRate = 0.0f;
}


//-----------------------------------------------------------------------------
// destructor
//-----------------------------------------------------------------------------
CGun::~CGun() {

  if (m_poParticle) {

    delete m_poParticle;
    m_poParticle = NULL;
  }
}


//-----------------------------------------------------------------------------
// Initialize the gun
//-----------------------------------------------------------------------------
bool CGun::Init(const char *pszShotFilename, float fSpeed, float fDamage, float fFireRate) {

  if (m_poParticle) {

    delete m_poParticle;
    m_poParticle = NULL;
  }

  m_poParticle = new CParticle();
  if (!m_poParticle->Init(pszShotFilename))
    return false;

  m_fSpeed    = fSpeed;
  m_fDamage   = fDamage;
  m_fFireRate = fFireRate;

  return true;
}


//-----------------------------------------------------------------------------
// add ammo
//-----------------------------------------------------------------------------
void CGun::AddAmmo(int nAmount) {

  m_nAmmo += nAmount;
}


//-----------------------------------------------------------------------------
// return a new shot
//-----------------------------------------------------------------------------
SShot CGun::GetShot(float *pfPos, float *pfDir, float fLife) {

  SShot stShot;

  memcpy(stShot.afPos, pfPos, sizeof(float) * 3);
  memcpy(stShot.afDir, pfDir, sizeof(float) * 3);
  stShot.fLife = fLife;
  stShot.poParticle = m_poParticle;
  stShot.fSpeed = m_fSpeed;
  stShot.fDamage = m_fDamage;

  return stShot;
}
